﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.Linq;
using System.Collections.Generic;
using System.Drawing;

namespace WebArchivosTelefonica.Jerarquias
{
    /// <summary>
    /// Clase de la implementación del control de documentacion de un candidato
    /// </summary>
    public partial class ControlDocumentacion : System.Web.UI.UserControl
    {
        #region CAMPOS

        private Color _backColorPestañaNormal;
        private Color _backColorPestañaResaltada;
        private Color _borderColorPestañaNormal;
        private Color _borderColorPestañaResaltada;
        private const int indiceDataKeyIdEstado = 1;

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            //Colores de los botones
            _backColorPestañaNormal = Color.FromArgb(102, 153, 255);
            _backColorPestañaResaltada = Color.FromArgb(0, 102, 255);
            _borderColorPestañaNormal = Color.FromArgb(153, 153, 153);
            _borderColorPestañaResaltada = Color.FromArgb(204, 204, 204);
        }

        /// <summary>
        /// evento que intercepta el rowcommand del gridview para poder subir el archivo
        /// cargado en el fileupload pues el gridview no lo hace automaticamente.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void _gridViewDocumentos_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            Administrador admin = new Administrador(new FabricaLinqDataSource(), new EntidadLinqDataContext());

            int filaActualizada = int.Parse(e.CommandArgument.ToString());
            string idDocumento = _gridViewDocumentos.DataKeys[filaActualizada].Value.ToString();
            string idEstado = string.Empty;
            if (((Guid?)(_gridViewDocumentos.DataKeys[filaActualizada].Values[indiceDataKeyIdEstado])).HasValue)
                idEstado = (_gridViewDocumentos.DataKeys[filaActualizada].Values[indiceDataKeyIdEstado]).ToString();


            if (e.CommandName == "Ver")
            {
                DataClassesArbolDataContext dc = new DataClassesArbolDataContext();
                Documento documentoModificado = dc.Documentos.Single(x => x.Id == new Guid(idDocumento));


                if (documentoModificado != null)
                {
                    string fileName = documentoModificado.Nombre;

                    Response.Clear();

                    //Este tipo usado sirve para Firefox 3 y IE 7
                    Response.ContentType = "application/" + fileName.Split(new char[1] { '.' })[1];

                    //Poner el nombre en comillas evita que algunos exploradores corten el nombre del archivo
                    //al encontrar espacios en blanco.
                    Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
                    Response.BinaryWrite(documentoModificado.Archivo.ToArray());
                    Response.End();
                }
            }

            if (e.CommandName == "Aprobar")
            {
                admin.AprobarDocumento(HiddenFieldIdProyecto.Value, idDocumento, idEstado);
                admin.AplicarCambios();
                _gridViewDocumentos.DataBind();

            }

            if (e.CommandName == "Rechazar")
            {
                admin.RechazarDocumento(HiddenFieldIdProyecto.Value, idDocumento, idEstado);
                admin.AplicarCambios();
                _gridViewDocumentos.DataBind();
            }
            if (e.CommandName == "Update")
            {
                FileUpload fileUploadArchivo = _gridViewDocumentos.Rows[filaActualizada].FindControl("_fileUploadDocumentos") as FileUpload;

                TextBox textBoxDescripcion = _gridViewDocumentos.Rows[filaActualizada].FindControl("_textBoxDescripcion") as TextBox;

                CheckBox checkBoxFacturable = _gridViewDocumentos.Rows[filaActualizada].FindControl("_checkBoxFacturable") as CheckBox;

                IEntidadLinqDocumento documentoEditar = admin.GetDocumentoById(new Guid(idDocumento));

                if (fileUploadArchivo != null)
                {

                    documentoEditar.Fecha = DateTime.Now;
                    if (fileUploadArchivo.HasFile)
                    {
                        Binary archivo = new Binary(fileUploadArchivo.FileBytes);
                        documentoEditar.Archivo = archivo;
                        documentoEditar.Nombre = fileUploadArchivo.FileName;
                        //     if (idEstado == 0 || idEstado == 6)
                        //         documentoEditar.IdEstadoDocumento = 1;

                        //Se verifica que si no se habia subido archivo se cambia el estado a creado
                        if (/*(documentoEditar.IdEstadoDocumentoSeleccionado == admin.GetIdEstadoByNombre("Ninguno")) || */(documentoEditar.Estado == "Ninguno"))
                        {
                            documentoEditar.IdEstadoDocumentoSeleccionado = admin.GetIdEstadoByNombre("Creado");
                        }
                    }

                }

                documentoEditar.Facturable = checkBoxFacturable.Checked;

                if (textBoxDescripcion != null)
                {
                    documentoEditar.Descripcion = textBoxDescripcion.Text;
                }

                admin.AplicarCambios();




            }

            if (e.CommandName == "Borrar")
            {
                IEntidadLinqDocumento documentoBorrar = admin.GetDocumentoById(new Guid(idDocumento));

                documentoBorrar.Archivo = null;
                documentoBorrar.Nombre = string.Empty;
                documentoBorrar.IdEstadoDocumentoSeleccionado = admin.GetIdEstadoByNombre("Ninguno");
                admin.AplicarCambios();

                _gridViewDocumentos.DataBind();


            }

            admin.Dispose();


        }

        /// <summary>
        /// Método evento de databound de cada fila para administrar la visibilidad de los botones
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void _gridViewDocumentos_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            FileUpload fileuploadArchivo = e.Row.FindControl("_fileUploadDocumentos") as FileUpload;
            LinkButton linkButtonAprobar = e.Row.FindControl("_linkButtonAprobar") as LinkButton;
            LinkButton linkButtonRechazar = e.Row.FindControl("_linkButtonRechazar") as LinkButton;
            LinkButton linkButtonBorrar = e.Row.FindControl("_linkButtonBorrar") as LinkButton;

            Administrador admin = new Administrador(new FabricaLinqDataSource(), new EntidadLinqDataContext());


            //Se verifica primero que no se este en la fila de encabezado

            if (e.Row.RowIndex != -1)
            {
                //Se definen variables a usar
                Guid idProyecto = new Guid(HiddenFieldIdProyecto.Value);
                Guid idDocumento = new Guid(_gridViewDocumentos.DataKeys[e.Row.RowIndex].Values["Id"].ToString());
                string idEstadoSeleccionadoDataKey = string.Empty;
                if (((Guid?)(_gridViewDocumentos.DataKeys[e.Row.RowIndex].Values["IdEstadoDocumentoSeleccionado"])).HasValue)
                    idEstadoSeleccionadoDataKey = (_gridViewDocumentos.DataKeys[e.Row.RowIndex].Values["IdEstadoDocumentoSeleccionado"]).ToString();

                Guid idEstado;
                if (string.IsNullOrEmpty(idEstadoSeleccionadoDataKey))
                {
                    idEstado = new Guid();
                }
                else
                {
                    idEstado = new Guid(idEstadoSeleccionadoDataKey);
                }


                //se obtiene el usuario actual y sus roles
                MembershipUser user = Membership.GetUser();
                string[] rolesUsuario = Roles.GetRolesForUser(user.UserName);

                //se filtran los roles relacionados con visibilidad de estados
                //NOTA: si la convención cambia por alguna razón esta parte del código también debe modificarse
                List<string> rolesEstados = rolesUsuario.ToList().FindAll(x => x.StartsWith("Rol_Estado"));

                //se agrega el rol de creacion si se tiene pues el método lo necesita
                if (Roles.IsUserInRole("Creador"))
                    rolesEstados.Add("Creador");



                if (linkButtonAprobar != null)
                {
                    linkButtonAprobar.Enabled = admin.VisibilidadEstadoAprobacion(idProyecto, idEstado, idDocumento, rolesEstados.AsReadOnly());
                }

                if (linkButtonRechazar != null)
                {
                    linkButtonRechazar.Enabled = admin.VisibilidadEstadoRechazo(idProyecto, idEstado, idDocumento, rolesEstados.AsReadOnly());
                }

                if (fileuploadArchivo != null)
                {
                    fileuploadArchivo.Enabled = Roles.IsUserInRole("Creador");
                }

                //Solo se pueden borrar documentos si se es administrador
                if (linkButtonBorrar != null)
                {
                    linkButtonBorrar.Enabled = Roles.IsUserInRole("Administrador");
                }



            }

            admin.Dispose();
        }

        /// <summary>
        /// Método del evento de binding para evitar que si se esta editando y se cambia de tab
        /// quede seleccionada la fila como en edicíón
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void _linqDataSourceDocumentos_DataBinding(object sender, EventArgs e)
        {
            _gridViewDocumentos.EditIndex = -1;
        }

        /// <summary>
        /// Cambia los valores de la carpeta base seleccionada
        /// </summary>
        /// <param name="idCandidato">id del candidato</param>
        /// <param name="idProyecto">id del proyecto</param>
        /// <param name="nombreCarpetaBase">Nombre de la carpeta base</param>
        /// <param name="administrador">Administrador </param>
        public void CambiarValoresCarpeta(string idCandidato, string idProyecto, string nombreCarpetaBase, IAdministrador administrador)
        {



            //visualizacion de carpetas permitida
            //se obtiene el usuario actual y sus roles
            MembershipUser user = Membership.GetUser();
            string[] rolesUsuario = Roles.GetRolesForUser(user.UserName);

            //se filtran los roles relacionados con visibilidad de carpetas
            //NOTA: si la convención cambia por alguna razón esta parte del código también debe modificarse
            List<string> rolesCarpetas = rolesUsuario.ToList().FindAll(x => x.StartsWith("Rol_Carpeta"));

            //Rol Carpeta: “Rol_Carpeta”_IdCliente_IdProyecto_IdCarpeta
            //se llena una lista con los ids de carpetas permitidos
            List<Guid> idRolesCarpetas = new List<Guid>();
            foreach (string rolCarpeta in rolesCarpetas)
            {
                idRolesCarpetas.Add(new Guid(rolCarpeta.Split(new char[1] { '_' })[4]));
            }

            HiddenFieldIdCandidato.Value = idCandidato;
            List<InfoJerarquia> dataSourcePestañas = administrador.GetDataSourceCarpetasHijas(nombreCarpetaBase, idRolesCarpetas);
            _barraBotonesDocumentos.DataSource = dataSourcePestañas;
            _barraBotonesDocumentos.DataBind();

            HiddenFieldIdCandidato.Value = idCandidato;
            HiddenFieldIdProyecto.Value = idProyecto;
            float porcentaje = (administrador.CalcularProcentajeCandidato(new Guid(HiddenFieldIdCandidato.Value))) * 100;

            _labelPorcentajeCandidato.Text = porcentaje.ToString() + "%";
        }

        /// <summary>
        /// Seleccionar pestaña
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        protected void _barraBotonesDocumentos_ItemCommand(object source, RepeaterCommandEventArgs e)
        {

            if (e.CommandName == "Seleccionar")
            {
                SeleccionarPestaña(e.Item.ItemIndex, e.Item);
            }
        }


        /// <summary>
        /// Selecciona la pestaña del item  
        /// </summary>
        /// <param name="indexPestaña"></param>
        /// <param name="item"></param>
        private void SeleccionarPestaña(int indexPestaña, RepeaterItem item)
        {
            NormalizarBotones();
            Button botonBarra = item.FindControl("_botonPestañaDataSource") as Button;
            ResaltarBoton(botonBarra);

            HiddenField id = item.FindControl("_hiddenFieldId") as HiddenField;



            string idCarpeta = id.Value;
            HiddenFieldIdCarpeta.Value = idCarpeta;

            ConfigurarDataSourceControl();
            _linqDataSourceDocumentos.DataBind();
            HiddenField nombreCarpeta = item.FindControl("_hiddenFieldNombreCarpeta") as HiddenField;

            Administrador admin = new Administrador(new FabricaLinqDataSource(), new EntidadLinqDataContext());

            string idCandidato = HiddenFieldIdCandidato.Value;
            string idProyecto = HiddenFieldIdProyecto.Value;
            Guid idCarpetaOtros = admin.GetIdCarpetaOtros(nombreCarpeta.Value, new Guid(idCandidato));

            ControlOtrosDocumentos1.CambiarValoresCarpeta(idCandidato, idProyecto, nombreCarpeta.Value, admin);
            ControlOtrosDocumentos1.Visible = true;
        }

        /// <summary>
        /// Normaliza los botones del repeater
        /// </summary>
        private void NormalizarBotones()
        {
            for (int i = 0; i < _barraBotonesDocumentos.Items.Count; i++)
            {
                Button botonBarra = _barraBotonesDocumentos.Items[i].FindControl("_botonPestañaDataSource") as Button;

                NormalizarBoton(botonBarra);

            }
        }



        /// <summary>
        /// Resalta boton de la pestaña
        /// </summary>
        /// <param name="boton"></param>
        private void ResaltarBoton(Button boton)
        {
            boton.BackColor = _backColorPestañaResaltada;
            boton.BorderColor = _borderColorPestañaResaltada;
        }
        /// <summary>
        /// Normaliza el boton de la pestaña
        /// </summary>
        /// <param name="boton"></param>
        private void NormalizarBoton(Button boton)
        {
            boton.BackColor = _backColorPestañaNormal;
            boton.BorderColor = _borderColorPestañaNormal;
        }




        /// <summary>
        /// Configura el datasource de el gridview de los documentos
        /// </summary>
        private void ConfigurarDataSourceControl()
        {
            Administrador admin = new Administrador(new FabricaLinqDataSource(), new EntidadLinqDataContext());

            float porcentaje = (admin.CalcularProcentajeCandidato(new Guid(HiddenFieldIdCandidato.Value))) * 100;
            if (float.IsNaN(porcentaje) || float.IsInfinity(porcentaje))
            {
                _labelPorcentajeCandidato.Text = "No existen documentos relevantes para calcular este porcentaje";
            }
            else
            {
                _labelPorcentajeCandidato.Text = porcentaje.ToString() + "%";
            }




            // creamos un string con la sentencia vacia
            string sentenciaWhere = string.Empty;
            // si hay valor en las cajas de texto se usa el valor de la propiedad
            // Text para incluir dicho valor en el filtrado de los datos.
            sentenciaWhere += "JerarquiaCarpeta.Id == Guid(@IdCarpeta) && AsociacionCandidatoDocumento.IdCandidato == Guid(@IdCandidato) && IdProyecto == Guid(@IdProyecto)";
            _linqDataSourceDocumentos.Where = sentenciaWhere;
            admin.Dispose();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void _gridViewDocumentos_RowUpdated(object sender, GridViewUpdatedEventArgs e)
        {
            ConfigurarDataSourceControl();
            _linqDataSourceDocumentos.DataBind();
            _gridViewDocumentos.DataBind();
        }
    }
}
